<script setup lang="ts">
import RoomStatus from './components/RoomStatus.vue'
import RoomAction from './components/RoomAction.vue'
import RoomMessage from './components/RoomMessage.vue'
import { io, Socket } from 'socket.io-client';
import { nextTick, onMounted, provide, ref } from 'vue';
import { baseURL } from '@/utils/request';
import { useUserStore } from '@/stores';
import { useRoute } from 'vue-router';
import type { Message, TimeMessages } from '@/types/room';
import { MsgType, OrderType } from '@/enums';
import type { ConsultOrderItem, Image } from '@/types/consult';
import { getConsultOrderDetail } from '@/apis/consult';
import dayjs from 'dayjs';
import { showToast } from 'vant';
defineOptions({
  name: 'ChatIndex'
})
const store = useUserStore()
const route = useRoute()
const loading = ref(false)
// 如果用户是第一次获取聊天记录 应该让 浏览器滚动到最底部
// 定义变量 初始值 为 true 判断这个值是不是true 认为它是第一次 当它进来后 我们就将这个值设置为 false
let initMsg = ref(true)
const list = ref<Message[]>([])
const consultOrderDetaitl = ref<ConsultOrderItem>()
const getconsultOrderDetail = async () => {
  const res = await getConsultOrderDetail(route.query.orderId as string)
  consultOrderDetaitl.value = res.data
}
//创建一个WebSocket连接
let socket: Socket
//挂载
onMounted(() => {
  getconsultOrderDetail()
  socket = io(baseURL, {
    auth: {
      token: `Bearer ${store.userInfo?.token}`
    },
    query: {
      orderId: route.query.orderId
    }
  })
  socket.on('connect', () => {
    //连接成功
    console.log('连接成功');

  })
  //接收消息
  socket.on('disconect', () => {
    //关闭连接
    console.log('断开连接');

  })
  socket.on('chatMsgList', async ({ data }: { data: TimeMessages[] }) => {
    const arr: Message[] = []
    data.forEach((item, i) => {
      if (i === 0) time.value = item.createTime
      arr.push({
        id: item.createTime,
        msg: { content: item.createTime },
        createTime: item.createTime,
        msgType: MsgType.Notify
      })
      arr.push(...item.items)
    })
    list.value.unshift(...arr)
    loading.value = false
    if (!arr.length) return showToast('没有聊天记录了')
    // 判断是不是第一次
    if (initMsg.value) {
      socket.emit('updateMsgStatus', arr[arr.length - 1].id)
      // 需要让浏览器滚动到最底部
      await nextTick()
      window.scrollTo(0, document.body.scrollHeight)
      // 需要将 initMsg 变量的值设置为 false
      initMsg.value = false
    }
  })
  //订单状态改变
  socket.on('statusChange', () => {
    getconsultOrderDetail()
  })

  // 接收聊天的消息(患者发出)
  socket.on('receiveChatMsg', async (event) => {
    socket.emit('updateMsgStatus', event.id)
    // console.log(event)
    list.value.push(event)
    // 让滚动条滚动到浏览器的最底部
    await nextTick()
    window.scrollTo(0, document.body.scrollHeight)
  })
  //聊天出现错误
  socket.on('error', (err) => {
    console.log(err);

  })
})
// 接收子组件提交过来的文本
const onSendMsg = (msg: string) => {
  // console.log(msg)
  // 将文字发送给医生端
  //sendChatMsg 接口文档，和后端商量的
  socket.emit('sendChatMsg', {

    // from 发送人
    from: store.userInfo?.id,
    // to 接受人
    to: consultOrderDetaitl.value?.docInfo?.id,
    msgType: MsgType.MsgText,
    msg: {
      content: msg
    }
  })
}
// 接收子组件提交过来的图片
const onSendImg = (img: Image) => {
  // console.log(msg)
  // 将文字发送给医生端
  //sendChatMsg 接口文档，和后端商量的
  socket.emit('sendChatMsg', {
    // from 发送人
    from: store.userInfo?.id,
    // to 接受人
    to: consultOrderDetaitl.value?.docInfo?.id,
    msgType: MsgType.MsgImage,
    msg: {
      picture: img
    }
  })
}
const time = ref(dayjs().format('YYYY-MM-DD HH:mm:ss'))
const onRefresh = () => {
  // 下拉刷新时 找服务器获取更多的聊天记录
  socket.emit('getChatMsgList', 20, time.value, route.query.orderId)
}
//跨组件（evaluteCard)通信，传参
provide('consult', consultOrderDetaitl)
//跨组件（evaluteCard)通信，传函数
const updateEav = (score: number) => {
  const item = list.value.find((item) => item.msgType === MsgType.CardEvaForm)
  if (item) {
    //给评价信息添加一个内容 使用{score}是一个对象 不然item.msg.evaluateDoc无法判断是否定义
    item.msg.evaluateDoc = { score },
      item.msgType = MsgType.CardEva
  }
}
provide('updateEav', updateEav)
</script>

<template>
  <div class="room-page">
    <cp-nav-bar title="问诊室" />
    <room-status :status="consultOrderDetaitl?.status" :countdown="consultOrderDetaitl?.countdown">
    </room-status>
    <van-pull-refresh v-model="loading" @refresh="onRefresh">
      <room-message v-for="item in list" :key="item.id" :item="item"></room-message>
    </van-pull-refresh>
    <room-action :disabled="consultOrderDetaitl?.status !== OrderType.ConsultChat" @send-img="onSendImg"
      @send-msg="onSendMsg"></room-action>
  </div>
</template>

<style lang="scss" scoped>
.room-page {
  padding-top: 90px;
  padding-bottom: 60px;
  min-height: 100vh;
  box-sizing: border-box;
  background-color: var(--cp-bg);

  .van-pull-refresh {
    width: 100%;
    min-height: calc(100vh - 150px);
  }
}
</style>

<style lang="scss" scoped>
.room-status {
  position: fixed;
  left: 0;
  top: 46px;
  height: 44px;
  width: 100%;
  background-color: #fff;
  font-size: 13px;
  z-index: 1;

  .wait {
    padding: 0 15px;
    background-color: var(--cp-plain);
    height: 100%;
    line-height: 44px;
    text-align: center;
    color: var(--cp-primary);
  }

  .chat {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 15px;

    span {
      &:first-child {
        color: var(--cp-primary);
      }

      &:last-child {
        color: var(--cp-text2);
        width: 130px;

        .van-count-down {
          display: inline;
        }
      }
    }
  }

  .end {
    display: flex;
    align-items: center;
    height: 44px;
    padding: 0 15px;
    font-weight: 500;

    .van-icon {
      font-size: 14px;
      margin-right: 4px;
      position: relative;
      top: 1px;
    }
  }
}
</style>